"""
认证模块依赖

提供认证相关的依赖函数，如获取当前用户、验证权限等。
这些依赖可以在FastAPI路由中使用。
"""

from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from jose import jwt, JWTError
from pydantic import ValidationError
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select

from app.core.config import settings
from app.core.security import ALGORITHM
from app.db.session import get_db
from app.models.user import User
from app.modules.auth.schemas import TokenPayload
from app.modules.auth.config import settings as auth_settings

# 创建OAuth2密码Bearer实例，指定token URL
oauth2_scheme = OAuth2PasswordBearer(tokenUrl=f"{settings.API_V1_STR}{auth_settings.API_PREFIX}/login")


async def get_current_user(
    db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)
) -> User:
    """
    获取当前用户（通过JWT令牌验证）
    
    验证JWT令牌并返回对应的用户对象。
    
    Args:
        db: 数据库会话
        token: JWT访问令牌
        
    Returns:
        当前认证用户对象
        
    Raises:
        HTTPException: 如果令牌无效或用户不存在
    """
    try:
        # 解码JWT令牌
        payload = jwt.decode(
            token, settings.SECRET_KEY, algorithms=[ALGORITHM]
        )
        token_data = TokenPayload(**payload)
        
        # 检查令牌是否已过期
        if token_data.exp is None:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="令牌缺少过期信息",
                headers={"WWW-Authenticate": "Bearer"},
            )
            
    except (JWTError, ValidationError):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="无法验证凭据",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    # 获取用户
    stmt = select(User).where(User.id == token_data.sub)
    result = await db.execute(stmt)
    user = result.scalar_one_or_none()
    
    if not user:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, 
            detail="未找到用户"
        )
    
    # 检查用户是否激活
    if not user.is_active:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, 
            detail="用户未激活"
        )
        
    return user


async def get_current_active_superuser(
    current_user: User = Depends(get_current_user),
) -> User:
    """
    获取当前超级用户
    
    验证当前用户是否为超级用户。
    
    Args:
        current_user: 当前认证用户
        
    Returns:
        当前认证的超级用户
        
    Raises:
        HTTPException: 如果用户不是超级用户
    """
    if not current_user.is_superuser:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="用户权限不足"
        )
    return current_user


async def get_current_verified_user(
    current_user: User = Depends(get_current_user),
) -> User:
    """
    获取当前已验证邮箱的用户
    
    验证当前用户是否已验证邮箱。
    
    Args:
        current_user: 当前认证用户
        
    Returns:
        当前已验证邮箱的用户
        
    Raises:
        HTTPException: 如果用户未验证邮箱
    """
    if auth_settings.EMAIL_VERIFICATION_REQUIRED and not current_user.is_email_verified:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="请先验证您的邮箱"
        )
    return current_user 